module main

fn assert_lexer(input string, expected []Token) {
	mut l := Lexer.new(input)

	for idx, exp_token in expected {
		recv_token := l.next_token()
		assert exp_token.kind == recv_token.kind
		assert exp_token.literal == recv_token.literal
	}
}

fn test_lexer() {
	input := ' = + () {}, []:;'
	expected := [
		Token{
			kind: TokenKind.assign
			literal: '='
		},
		Token{
			kind: TokenKind.plus
			literal: '+'
		},
		Token{
			kind: TokenKind.lparen
			literal: '('
		},
		Token{
			kind: TokenKind.rparen
			literal: ')'
		},
		Token{
			kind: TokenKind.lbrace
			literal: '{'
		},
		Token{
			kind: TokenKind.rbrace
			literal: '}'
		},
		Token{
			kind: TokenKind.comma
			literal: ','
		},
		Token{
			kind: TokenKind.lbracket
			literal: '['
		},
		Token{
			kind: TokenKind.rbracket
			literal: ']'
		},
		Token{
			kind: TokenKind.colon
			literal: ':'
		},
		Token{
			kind: TokenKind.semicolon
			literal: ';'
		},
		Token{
			kind: TokenKind.eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}

fn test_lexer_number() {
	input := '123'

	expected := [
		Token{
			kind: TokenKind.integer
			literal: '123'
		},
		Token{
			kind: TokenKind.eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}

fn test_lexer_identifier() {
	input := 'abc_xxx'

	expected := [
		Token{
			kind: TokenKind.identifier
			literal: 'abc_xxx'
		},
		Token{
			kind: TokenKind.eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}

fn test_lexer_keywords() {
	input := 'fn abc let'

	expected := [
		Token{
			kind: TokenKind.function
			literal: 'fn'
		},
		Token{
			kind: TokenKind.identifier
			literal: 'abc'
		},
		Token{
			kind: TokenKind.let
			literal: 'let'
		},
		Token{
			kind: TokenKind.eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}

fn test_lexer_string() {
	input := '"Hello World!"'

	expected := [
		Token{
			kind: TokenKind.string
			literal: 'Hello World!'
		},
		Token{
			kind: TokenKind.eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}

fn test_lexer_than() {
	input := '== != ! > >= < <='

	expected := [
		Token{
			kind: .equal
			literal: '=='
		},
		Token{
			kind: .bang_equal
			literal: '!='
		},
		Token{
			kind: .bang
			literal: '!'
		},
		Token{
			kind: .greater
			literal: '>'
		},
		Token{
			kind: .greater_equal
			literal: '>='
		},
		Token{
			kind: .less
			literal: '<'
		},
		Token{
			kind: .less_equal
			literal: '<='
		},
		Token{
			kind: .eof
			literal: ' '
		},
	]

	assert_lexer(input, expected)
}
